package com.joker.airoleplayplatformback.task;

import com.joker.airoleplayplatformback.utils.WebSocketConnectionManager;
import com.joker.airoleplayplatformback.websocket.VoiceChatWebSocketHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Map;

/**
 * WebSocket心跳检测定时任务
 *
 * @author feixiang.li
 * @since 2025-09-27
 */
@Slf4j
@Component
public class WebSocketHeartbeatTask {

    @Autowired
    private VoiceChatWebSocketHandler voiceChatWebSocketHandler;


    @Autowired
    private WebSocketConnectionManager webSocketConnectionManager;

    // 心跳超时时间（毫秒）- 60秒
    private static final long HEARTBEAT_TIMEOUT = 60000;

    /**
     * 每30秒检查一次心跳
     */
    @Scheduled(fixedRate = 30000)
    public void checkHeartbeat() {
        try {
            long currentTime = System.currentTimeMillis();
            Map<String, Long> heartbeatMap = voiceChatWebSocketHandler.getSessionHeartbeatMap();
            Map<String, WebSocketSession> sessions = voiceChatWebSocketHandler.getSessions();

            int totalSessions = sessions.size();
            int timeoutSessions = 0;

            for (Map.Entry<String, Long> entry : heartbeatMap.entrySet()) {
                String sessionId = entry.getKey();
                Long lastHeartbeat = entry.getValue();

                if (currentTime - lastHeartbeat > HEARTBEAT_TIMEOUT) {
                    // 心跳超时，关闭连接
                    WebSocketSession session = sessions.get(sessionId);
                    if (session != null && session.isOpen()) {
                        try {
                            log.warn("会话心跳超时，主动关闭连接: {}, 超时时间: {}ms",
                                    sessionId, currentTime - lastHeartbeat);
                            session.close();
                            timeoutSessions++;
                        } catch (IOException e) {
                            log.error("关闭超时会话失败: {}", sessionId, e);
                        }
                    }
                }
            }

            if (totalSessions > 0) {
                log.debug("心跳检测完成 - 总会话数: {}, 超时会话数: {}", totalSessions, timeoutSessions);
            }

        } catch (Exception e) {
            log.error("心跳检测任务执行失败", e);
        }
    }

    /**
     * 每5分钟发送主动心跳
     */
    @Scheduled(fixedRate = 300000)
    public void sendActiveHeartbeat() {
        try {
            Map<String, WebSocketSession> sessions = voiceChatWebSocketHandler.getSessions();

            for (Map.Entry<String, WebSocketSession> entry : sessions.entrySet()) {
                String sessionId = entry.getKey();
                WebSocketSession session = entry.getValue();

                if (session.isOpen()) {
                    webSocketConnectionManager.sendMessage(sessionId, Map.of(
                            "type", "server_heartbeat",
                            "timestamp", System.currentTimeMillis(),
                            "message", "服务器心跳检测"
                    ));
                }
            }

            if (sessions.size() > 0) {
                log.debug("服务器主动心跳已发送，会话数: {}", sessions.size());
            }

        } catch (Exception e) {
            log.error("发送主动心跳失败", e);
        }
    }
}
